package com.sinosun.autotestmachine.tools.proxy;

import java.util.ArrayList;
import java.util.List;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.sinosun.autotestmachine.App;
import com.sinosun.autotestmachine.tools.ValueInfo;
import com.sinosun.autotestmachine.tools.ValueType;
import com.sinosun.autotestmachine.tools.Collector.Cache;
import com.sinosun.autotestmachine.tools.Collector.FileCancelCollector;
import com.sinosun.autotestmachine.tools.Collector.FileloadCollector;
import com.sinosun.autotestmachine.tools.parser.ContentMaker;
import com.sinosun.autotestmachine.tools.parser.FileDetail;
import com.sinosun.autotestmachine.tools.parser.FileInfoHolder;
import com.sinosun.autotestmachine.tools.parser.FileType;
import com.sinosun.autotestmachine.tools.parser.ParamKey;
import com.sinosun.autotestmachine.tools.proxy.callback.CallbackWrapper;
import com.sinosun.autotestmachine.tools.proxy.callback.FileloadInfo;
import com.sinosun.autotestmachine.tools.utils.Md5Util;
import com.sinosun.autotestmachine.tools.utils.Utils;
import com.sinosun.mstplib.FilePolicy;
import com.sinosun.mstplib.MstpClient;
import com.sinosun.mstplib.MstpException;
import com.sinosun.mstplib.clouddisk.ImagePolicy;

import android.text.TextUtils;
import android.util.Log;

public class FileModule {
	
	protected static int syncUploadFile(MstpClient mstpClient, String paramJson, String cacheJson) {
		List<String> params = new ArrayList<String>();
		List<String> caches = new ArrayList<String>();
		try {
			JSONObject paramJo = new JSONObject(paramJson);
			if (paramJo.has(ParamKey.FILE_CONTENT_ID)) {
				JSONArray paramJa = paramJo.getJSONArray(ParamKey.FILE_CONTENT_ID);
				for (int i = 0; i < paramJa.length(); i++) {
					String tmp = paramJa.getString(i);
					ValueInfo vi = Utils.getMsgRealInfo(tmp);
					if (vi.getValueType() == ValueType.INDEX) {
						tmp = App.getTestConfig().getFileContent().get(vi.getValueContent());
					} else {
						tmp = vi.getValueContent();
					}
					params.add(tmp);
				}
			} else {
				return ErrorCode.ERR_PARAM_ERROR;
			}
			
			if (cacheJson != null) {
				JSONObject cacheJo = new JSONObject(cacheJson);
				if (cacheJo.has(ParamKey.FILE_ID)) {
					JSONArray ja = cacheJo.getJSONArray(ParamKey.FILE_ID);
					for (int i = 0; i < ja.length(); i++) {
						caches.add(ja.getString(i));
					}
				} else {
					return ErrorCode.ERR_PARAM_ERROR;
				}
			}
		} catch (JSONException e1) {
			return ErrorCode.ERR_PARAM_ERROR;
		}
		
		if (params.size() <= 0 || caches.size() < 0) {
			return ErrorCode.ERR_PARAM_ERROR;
		}
		
		FileloadCollector collector = new FileloadCollector();
		List<FileDetail> allFile = new ArrayList<FileDetail>();
		for (String param : params) {
			FileInfoHolder get = ContentMaker.getFileInfoHolder(param);
			if (get == null) {
				return ErrorCode.ERR_PARAM_ERROR;
			}
			if (get.getFilesize() < 0) {
				return ErrorCode.ERR_PARAM_ERROR;
			}
			
			String filePath = new String();
			FilePolicy policy = new FilePolicy();
			String name = get.getFileName();
			
			if (get.getFileType() == FileType.FILE.value()) {
				name = ContentMaker.generateSizedFile(App.getInstance().getUploadPath(), (int)get.getFilesize(), name);
			} else if (get.getFileType() == FileType.IMAGE.value()) {
				name = ContentMaker.generateImageFile(App.getInstance().getUploadPath(), name);
				if (!TextUtils.isEmpty(get.getImagePolicy())) {
					ImagePolicy ip = new ImagePolicy();
					policy.setImagePolicy(ip.toString());
				}
			} else if (get.getFileType() == FileType.AUDIO.value()) {
				name = ContentMaker.generateSizedAudioFile(App.getInstance().getUploadPath(), (int)get.getFilesize(), name);
			} else if (get.getFileType() == FileType.VIDEO.value()) {
				name = ContentMaker.generateSizedVideoFile(App.getInstance().getUploadPath(), (int)get.getFilesize(), name);
			} else {
				return ErrorCode.ERR_PARAM_ERROR;
			}
			
			policy.setEncrypt(get.getEncrypt() != 0);
			filePath = App.getInstance().getUploadPath() + name;
			
			FileDetail item = new FileDetail();
			item.setMD5(Md5Util.getFileMD5(filePath));
			item.setFileType(FileType.valueOf(get.getFileType()));
			item.setInCache(true);
			allFile.add(item);
			try {
				String actionId = mstpClient.uploadFile(filePath, policy, false);
				FileloadInfo ele = new FileloadInfo();
				ele.setTrasactionId(actionId);
				collector.addFileID(ele);
			} catch (MstpException e) {
				return e.getErrorCode();
			}
		}
		CallbackWrapper.makeFileUploadCallback(collector);
		try {
			collector.waitResult();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		if (collector.getResult() == ErrorCode.SUCCESS) {			//将收集到的 fileID信息存入缓存
			for (int i = 0; i < caches.size(); i++) {
				allFile.get(i).setFileId(collector.getFileInfos().get(i).getFileId());
				Cache.allUploadFile.put(caches.get(i), allFile.get(i));
			}
		}
		return collector.getResult();
	}
	
	protected static int syncDownloadFile(MstpClient mstpClient, String paramJson) {
		List<FileDetail> fileIds = new ArrayList<FileDetail>();
		int encrypt = -1;
		String imgPolicy = null;
		try {
			JSONObject jo = new JSONObject(paramJson);
			if (jo.has(ParamKey.FILE_ID)) {
				JSONArray ja  = jo.getJSONArray(ParamKey.FILE_ID);
				for (int i = 0; i < ja.length(); i++) {
					String tmp = ja.getString(i);
					ValueInfo vi = Utils.getFileIDRealInfo(tmp);
					if (vi.getValueType() == ValueType.INDEX) {
						FileDetail fd = new FileDetail();
						if (Cache.allUploadFile.get(tmp) != null) {
							fd = Cache.allUploadFile.get(tmp);
						} else {
							return ErrorCode.ERR_PARAM_ERROR;
						}
						fileIds.add(fd);
					} else {
						FileDetail fd = new FileDetail();
						fd.setFileId(tmp);
						fd.setInCache(false);
						fileIds.add(fd);
					}
				}
			} else {
				return ErrorCode.ERR_PARAM_ERROR;
			}
			if (jo.has(ParamKey.ENCRYPT)) {
				encrypt = jo.getInt(ParamKey.ENCRYPT);
			} else {
				return ErrorCode.ERR_PARAM_ERROR;
			}
			if (jo.has(ParamKey.IMAGE_POLICY)) {
				imgPolicy = jo.getString(ParamKey.IMAGE_POLICY);
			} else {
				return ErrorCode.ERR_PARAM_ERROR;
			}
			
		} catch (JSONException e) {
			e.printStackTrace();
		}
		
		FilePolicy fp = new FilePolicy();
		
		if (fileIds.size() <= 0) {
			return ErrorCode.ERR_PARAM_ERROR;
		}
		if (encrypt != -1) {
			fp.setEncrypt(encrypt != 0);
		}
		if (imgPolicy.startsWith("{") && imgPolicy.endsWith("}") && imgPolicy.length() >= 3) {
			fp.setImagePolicy(imgPolicy);
		}
		
		FileloadCollector collector = new FileloadCollector();
		List<FileDetail> downLoadFiles = new ArrayList<FileDetail>();
		for (FileDetail fileId : fileIds) {
			String storePath = App.getInstance().getDownloadPath() + System.currentTimeMillis();
			if (fileId.getInCache()) {
				FileDetail cpItem = new FileDetail();
				cpItem.setFileId(fileId.getFileId());
				cpItem.setMD5(storePath);		//此时没有文件，不能获取 MD5，暂存路径用于获取 MD5
				downLoadFiles.add(cpItem);
			}
			try {
				String actionId = mstpClient.downloadFile(fileId.getFileId(), storePath, fp);
				FileloadInfo fi = new FileloadInfo();
				fi.setTrasactionId(actionId);
				collector.addFileID(fi);
			} catch (MstpException e) {
				e.printStackTrace();
				return e.getErrorCode();
			}
		}
		
		CallbackWrapper.makeFileDownloadCallback(collector);
		try {
			collector.waitResult();
		} catch (InterruptedException e) {
			e.printStackTrace();
			return ErrorCode.ERR_UNEXPECT_RESULT;
		}
		CallbackWrapper.clearFileCallback();
		
		if (collector.getResult() != ErrorCode.SUCCESS) {
			return collector.getResult();
		}
		
		List<FileDetail> tagMap = new ArrayList<FileDetail>();
		for (FileDetail tmpFd : Cache.allUploadFile.values()) {
			FileDetail tagItem = new FileDetail();
			tagItem.setFileId(tmpFd.getFileId());
			tagItem.setMD5(tmpFd.getMD5());
			tagMap.add(tagItem);
		}
		
		for (int i = 0; i < downLoadFiles.size(); i++) {
			downLoadFiles.get(i).setMD5(Md5Util.getFileMD5(downLoadFiles.get(i).getMD5()));
		}
		
		if (tagMap.containsAll(downLoadFiles)) {
			return ErrorCode.SUCCESS;
		} else {
			return ErrorCode.ERR_UNEXPECT_RESULT;
		}
	}
	
	
	protected static int cancelUploadFileAndVerify(MstpClient mstpClient, String param) {
		List<String> allFileContent = new ArrayList<String>();
		int cancelPoint = 0;
		try {
			JSONObject jo = new JSONObject(param);
			if (jo.has(ParamKey.FILE_CONTENT_ID)) {
				JSONArray ja = jo.getJSONArray(ParamKey.FILE_CONTENT_ID);
				for (int i = 0; i < ja.length(); i++) {
					String tmp = ja.getString(i);
					ValueInfo vi = Utils.getMsgRealInfo(tmp);
					if (vi.getValueType() == ValueType.INDEX) {
						tmp = App.getTestConfig().getFileContent().get(vi.getValueContent());
					} else {
						tmp = vi.getValueContent();
					}
					allFileContent.add(tmp);
				}
			} else {
				return ErrorCode.ERR_PARAM_ERROR;
			}
			
			
			if (jo.has(ParamKey.CANCEL_POINT)) {
				cancelPoint = jo.getInt(ParamKey.CANCEL_POINT);
			} else {
				return ErrorCode.ERR_PARAM_ERROR;
			}
		} catch (JSONException e) {
			e.printStackTrace();
			return ErrorCode.ERR_PARAM_ERROR;
		}
		
		if (allFileContent.size() <= 0) {
			return ErrorCode.ERR_PARAM_ERROR;
		}
		
		FileCancelCollector collector = new FileCancelCollector();
		collector.setCancelPoint(cancelPoint);
		CallbackWrapper.makeFileUploadCallbackAndCancel(mstpClient, collector);
		for (String info : allFileContent) {
			FileInfoHolder get = ContentMaker.getFileInfoHolder(info);
			if (get == null || get.getFilesize() <= 0) {
				return ErrorCode.ERR_PARAM_ERROR;
			}
			
			FilePolicy policy = new FilePolicy();
			String name = get.getFileName();
			if (get.getFileType() == FileType.FILE.value()) {
				name = ContentMaker.generateSizedFile(App.getInstance().getUploadPath(), (int) get.getFilesize(), name);
			} else if (get.getFileType() == FileType.IMAGE.value()) {
				name = ContentMaker.generateImageFile(App.getInstance().getUploadPath(), name);
				if (!TextUtils.isEmpty(get.getImagePolicy())) {
					ImagePolicy ip = new ImagePolicy();
					policy.setImagePolicy(ip.toString());
				}
			} else if (get.getFileType() == FileType.AUDIO.value()) {
				name = ContentMaker.generateSizedAudioFile(App.getInstance().getUploadPath(), (int)get.getFilesize(), name);
			} else if (get.getFileType() == FileType.VIDEO.value()) {
				name = ContentMaker.generateSizedVideoFile(App.getInstance().getUploadPath(), (int)get.getFilesize(), name);
			} else {
				return ErrorCode.ERR_PARAM_ERROR;
			}
			policy.setEncrypt(get.getEncrypt() != 0);
			
			String filePath = new String();
			filePath = App.getInstance().getUploadPath() + name;
			
			try {
				String actionId = mstpClient.uploadFile(filePath, policy, false);
				collector.putTrasactionId(actionId, false);
				
			} catch (MstpException e) {
				e.printStackTrace();
				return ErrorCode.ERR_UNEXPECT_RESULT;
			}
		}
		
		try {
			collector.waitResult();
		} catch (InterruptedException e) {
			e.printStackTrace();
			return ErrorCode.ERR_UNEXPECT_RESULT;
		}
		
		return collector.getResult();
	}
	
	protected static int cancelDownloadFileAndVerify(MstpClient mstpClient, String paramJson) {
		List<String> fileIds = new ArrayList<String>();
		int cancelPoint = -1;
		try {
			JSONObject jo = new JSONObject(paramJson);
			if (jo.has(ParamKey.CANCEL_POINT)) {
				cancelPoint = jo.getInt(ParamKey.CANCEL_POINT);
			} else {
				return ErrorCode.ERR_PARAM_ERROR;
			}
			
			if (jo.has(ParamKey.FILE_ID)) {
				JSONArray ja  = jo.getJSONArray(ParamKey.FILE_ID);
				for (int i = 0; i < ja.length(); i++) {
					String tmp = ja.getString(i);
					ValueInfo vi = Utils.getFileIDRealInfo(tmp);
					if (vi.getValueType() == ValueType.INDEX) {
						fileIds.add(Cache.allUploadFile.get(tmp).getFileId());
					} else {
						fileIds.add(tmp);
					}
				}
			} else {
				return ErrorCode.ERR_PARAM_ERROR;
			}
		} catch (JSONException e1) {
			e1.printStackTrace();
			return ErrorCode.ERR_PARAM_ERROR;
		}
		
		FileCancelCollector collector = new FileCancelCollector();
		collector.setCancelPoint(cancelPoint);
		for (String fileId : fileIds) {
			Log.e("XXX", "cancelDownloadFileAndVerify fileId->" + fileId);
			try {
				String downLoadPath = App.getInstance().getDownloadPath() + System.currentTimeMillis();
				String actionId = mstpClient.downloadFile(fileId, downLoadPath, null);
				collector.putTrasactionId(actionId, false);
			} catch (MstpException e) {
				e.printStackTrace();
				return e.getErrorCode();
			}
		}
		CallbackWrapper.makeFileDownloadCallbackAndCancel(mstpClient, collector);
		
		try {
			collector.waitResult();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		return collector.getResult();
	}
	
	protected static int uploadDuplicateFileAndVerify(MstpClient mstpClient, String param) {
		String fileContent = null;
		try {
			JSONObject paramJo = new JSONObject(param);
			if (paramJo.has(ParamKey.FILE_CONTENT_ID)) {
				fileContent = paramJo.getString(ParamKey.FILE_CONTENT_ID);
				ValueInfo vi = Utils.getMsgRealInfo(fileContent);
				if (vi.getValueType() == ValueType.INDEX) {
					fileContent = App.getTestConfig().getFileContent().get(vi.getValueContent());
				} else {
					fileContent = vi.getValueContent();
				}
			} else {
				return ErrorCode.ERR_PARAM_ERROR;
			}
		} catch (JSONException e1) {
			return ErrorCode.ERR_PARAM_ERROR;
		}
		
		FileInfoHolder get = ContentMaker.getFileInfoHolder(fileContent);
		if (get == null) {
			return ErrorCode.ERR_PARAM_ERROR;
		}
		if (get.getFilesize() <= 0) {
			return ErrorCode.ERR_PARAM_ERROR;
		}
		
		String filePath = new String();
		FilePolicy policy = new FilePolicy();
		String name = get.getFileName();
		FileloadCollector collector = new FileloadCollector();
		if (get.getFileType() == FileType.FILE.value()) {
			name = ContentMaker.generateSizedFile(App.getInstance().getUploadPath(), (int)get.getFilesize(), name);
			Log.e("XXX", "upload file path is " + App.getInstance().getUploadPath() + name);
		} else if (get.getFileType() == FileType.IMAGE.value()) {
			name = ContentMaker.generateImageFile(App.getInstance().getUploadPath(), name);
			if (!TextUtils.isEmpty(get.getImagePolicy())) {
				ImagePolicy ip = new ImagePolicy();
				policy.setImagePolicy(ip.toString());
			}
		} else if (get.getFileType() == FileType.AUDIO.value()) {
			name = ContentMaker.generateSizedAudioFile(App.getInstance().getUploadPath(), (int)get.getFilesize(), name);
		} else if (get.getFileType() == FileType.VIDEO.value()) {
			name = ContentMaker.generateSizedVideoFile(App.getInstance().getUploadPath(), (int)get.getFilesize(), name);
		} else {
			return ErrorCode.ERR_PARAM_ERROR;
		}
		policy.setEncrypt(get.getEncrypt() != 0);
		filePath = App.getInstance().getUploadPath() + name;
		
		try {
			String actionId = mstpClient.uploadFile(filePath, policy, false);
			FileloadInfo ele = new FileloadInfo();
			ele.setTrasactionId(actionId);
			collector.addFileID(ele);
		} catch (MstpException e) {
			return e.getErrorCode();
		}
		CallbackWrapper.makeFileUploadCallback(collector);
		try {
			collector.waitResult();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		if (collector.getResult() != ErrorCode.SUCCESS) {			//将收集到的 fileID信息存入缓存
			return collector.getResult();
		}
		
		collector = new FileloadCollector();
		try {
			String trasactionId = mstpClient.uploadFile(filePath, policy, false);
			FileloadInfo ele = new FileloadInfo();
			ele.setTrasactionId(trasactionId);
			collector.addFileID(ele);
		} catch (MstpException e) {
			e.printStackTrace();
			return ErrorCode.ERR_UNEXPECT_RESULT;
		}
		
		CallbackWrapper.makeUploadDuplicateFileListener(collector);
		try {
			collector.waitResult();
		} catch (InterruptedException e) {
			e.printStackTrace();
			return ErrorCode.ERR_UNEXPECT_RESULT;
		}
		return collector.getResult();
	}
}
